﻿using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using AzukiMap.Tools;

namespace AzukiMap.MapSource
{
    public abstract class TileSource : MapSource
    {
        protected List<string> _baseUris;
        protected List<double> _scales;
        protected int _tileWidth;
        protected int _tileHeight;
        protected int _dpi = 72;

        XmlCommon _xmlCommon;

        public virtual List<string> BaseUris
        {
            set { _baseUris = value; }
            get { return _baseUris; }
        }

        public List<double> Scales
        {
            set
            {
                _scales = value;
                _scales.Sort();
            }
            get { return _scales; }
        }

        public int TileWidth
        {
            set { _tileWidth = value; }
            get { return _tileWidth; }
        }

        public int TileHeight
        {
            set { _tileHeight = value; }
            get { return _tileHeight; }
        }

        public int Dpi
        {
            set { _dpi = value; }
            get { return _dpi; }
        }

        public TileSource(string name, int srid, CoordinationUnits coordUnit)
            : base(name, MapSourceTypes.Tile, srid)
        {
            _baseUris = new List<string>();
            _scales = new List<double>();
            _xmlCommon = new XmlCommon();
        }

        public TileSource(string name, List<string> baseUris, int srid,
            CoordinationUnits coordUnit, int tileWidth, int tileHeight, List<double> scales, int dpi)
            : base(name, MapSourceTypes.Tile, srid)
        {
            _baseUris = baseUris;
            _tileWidth = tileWidth;
            _tileHeight = tileHeight;
            scales.Sort();
            _scales = scales;
            _scales.Sort();
            _dpi = dpi;
            _xmlCommon = new XmlCommon();
        }

        public override XElement ToXml()
        {
            return ToXml("TileSource");
        }

        public override XElement ToXml(string elementName)
        {
            XElement tileSourceXml = base.ToXml(elementName);
            tileSourceXml.Add(
                _xmlCommon.CreateAttr("TileWidth", _tileWidth),
                _xmlCommon.CreateAttr("TileHeight", _tileHeight),
                _xmlCommon.CreateAttr("Dpi", _dpi),
                new XElement("BaseUris",
                    from uri in _baseUris
                    select new XElement("Uri", uri)
                    ),
                new XElement("Scales",
                    from scale in _scales
                    select new XElement("Scale", scale)
                    )
                );

            return tileSourceXml;
        }

        public override void Parse(XElement mapSourceXml)
        {
            base.Parse(mapSourceXml);

            IEnumerable<string> uris =
                from uri in mapSourceXml.Element("BaseUris").Elements("Uri")
                select uri.Value;
            _baseUris = new List<string>(uris);

            IEnumerable<double> scales =
                from scale in mapSourceXml.Elements("Scales").Elements("Scale")
                select (double) scale;
            _scales = new List<double>(scales);

            _tileWidth = _xmlCommon.GetIntAttr(mapSourceXml, "TileWidth");
            _tileHeight = _xmlCommon.GetIntAttr(mapSourceXml, "TileHeight");
            _dpi = _xmlCommon.GetIntAttr(mapSourceXml, "Dpi");
        }

        int CompareDouble(double x, double y)
        {
            if (x < y)
                return -1;
            if (x == y)
                return 0;
            return 1;
        }
    }
}
